package com.xtm.exercise.utils;

import cn.hutool.core.date.DateTime;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 使用Joda-Time封装日期和时间，替代JDK
 * @author wanglei
 * @date 2019-03-25
 *
 *         <dependency>
 *             <groupId>joda-time</groupId>
 *             <artifactId>joda-time</artifactId>
 *         </dependency>
 */
public class DateTimeUtil {

	/**
	 * 获取当前日期和时间，默认格式"yyyy-MM-dd HH:mm:ss"
	 *
	 * @return 2019-03-25 10:00:00
	 */
	public static String getCurrentDate() {
		DateTime dateTime = new DateTime();
		return dateTime.toString("yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 获取当前时间，默认格式"HH:mm:ss"
	 *
	 * @return 10:10:00
	 */
	public static String getCurrentTime() {
		DateTime dateTime = new DateTime();
		return dateTime.toString("HH:mm:ss");
	}

	/**
	 * 获取当前年月日，默认格式"yyyy-MM-dd"
	 *
	 * @return 2019-03-25
	 */
	public static String getCurrentYearMonthDay() {
		DateTime dateTime = new DateTime();
		return dateTime.toString("yyyy-MM-dd");
	}

	/**
	 * 获取当前年月，默认格式"yyyy-MM"
	 *
	 * @return 2019-03
	 */
	public static String getCurrentYearMonth() {
		DateTime dateTime = new DateTime();
		return dateTime.toString("yyyy-MM");
	}

	/**
	 * 获取当前月日，默认格式"MM-dd"
	 *
	 * @return 03-25
	 */
	public static String getCurrentDateInMMdd() {
		DateTime dateTime = new DateTime();
		return dateTime.toString("MM-dd");
	}

	/**
	 * 获取当前年份
	 *
	 * @return 2019
	 */
	public static String getCurrentYear() {
		DateTime dateTime = new DateTime();
		return String.format("%4d", dateTime.getYear());
	}

	/**
	 * 获取当前月份，补齐位数
	 *
	 * @return 03
	 */
	public static String getCurrentMon() {
		DateTime dateTime = new DateTime();
		return String.format("%02d", dateTime.getMonthOfYear());
	}

	/**
	 * 获取当日，补齐位数
	 *
	 * @return 25
	 */
	public static String getCurrentDay() {
		DateTime dateTime = new DateTime();
		return String.format("%02d", dateTime.getDayOfMonth());
	}

	/**
	 * 获取上个月，默认格式"yyyy-MM"
	 *
	 * @return 2019-02
	 */
	public static String getYearLastMonth() {
		DateTime dateTime = new DateTime().minusMonths(1);
		return dateTime.toString("yyyy-MM");
	}

	/**
	 * 获取下个月，默认格式"yyyy-MM"
	 *
	 * @return 2019-04
	 */
	public static String getYearNextMonth() {
		DateTime dateTime = new DateTime().plusMonths(1);
		return dateTime.toString("yyyy-MM");
	}

	/**
	 * 获取几天前的日期，默认格式"yyyy-MM-dd"
	 *
	 * @param dayOfWeek
	 * @return 2019-02-28
	 */
	public static String getLastWeek(int dayOfWeek) {
		DateTime dateTime = new DateTime().minusDays(dayOfWeek);
		return dateTime.toString("yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 获取上周或上上周的某一天日期（几周几天之前），默认格式"yyyy-MM-dd"
	 *
	 * @param n 周数, dayOfWeek 天数
	 * @return 2019-02-28
	 */
	public static String getLastWeek(int n, int dayOfWeek) {
		DateTime dateTime = new DateTime().minusDays(n * 7 + dayOfWeek);
		return dateTime.toString("yyyy-MM-dd");
	}

	/**
	 * 获取上个月的最后一天，默认格式"yyyy-MM-dd"
	 *
	 * @return 2019-02-28
	 */
	public static String getLastMonLastDay() {
		DateTime dateTime = new DateTime().minusMonths(1).dayOfMonth().withMaximumValue();
		return dateTime.toString("yyyy-MM-dd");
	}

	/**
	 * 获取几天后的日期，默认格式"yyyy-MM-dd"
	 *
	 * @param offsetDays 偏移天数（可为负数，表示几天前）
	 * @return 2019-03-26
	 */
	public static String getOffsetDate(int offsetDays){
		DateTime dateTime = new DateTime().plusDays(offsetDays);
		return dateTime.toString("yyyy-MM-dd");
	}

	/**
	 * 格式化日期时间为指定格式的字符串，默认格式"yyyy-MM-dd HH:mm:ss"
	 *
	 * @param date 日期时间
	 * @return 指定格式的字符串日期
	 */
	public static String dateToStr(Date date, String formatStr) {
		if(date == null){
            return "null";
        }
		if(isBlank(formatStr)) {
			formatStr = "yyyy-MM-dd HH:mm:ss";
		}
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(formatStr);
	}

	/**
	 * 将字符串日期解析为日期对象，默认格式"yyyy-MM-dd HH:mm:ss"
	 *
	 * @param dateStr 字符串格式的日期时间
	 * @param formatStr 日期格式 例如：yyyyMMddHHmmss, yyyy-MM-dd HH:mm:ss
	 * @return 日期对象，解析失败返回null
	 */
	public static Date strToDate(String dateStr, String formatStr) {
		if(isBlank(formatStr)) {
			formatStr = "yyyy-MM-dd HH:mm:ss";
		}
		DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(formatStr);
		DateTime dateTime = dateTimeFormatter.parseDateTime(dateStr);
		return dateTime.toDate();
	}

	/**
	 * 获取当前日期对象
	 *
	 * @return 日期对象
	 */
	public static Date currentFormatDate(){
		DateTime dateTime = new DateTime();
		return dateTime.toDate();
	}

	public static final boolean isBlank(String value){
		int strLen;
		if (value == null || (strLen = value.length()) == 0) {
			return true;
		}
		for (int i = 0; i < strLen; i++) {
			if (Character.isWhitespace(value.charAt(i)) == false) {
				return false;
			}
		}
		return true;
	}

	/*
     * @Description: 获取指定某年某月份的最后一天
     * @Date 2019/6/3 10:52
     * @param: yearMonth yyyy-MM格式  2018-12
     * @return: java.lang.String
     */
    public static String getLastDayOfMonth(String yearMonth) {
        int year = Integer.parseInt(yearMonth.split("-")[0]);  //年
        int month = Integer.parseInt(yearMonth.split("-")[1]); //月
        Calendar cal = Calendar.getInstance();
        // 设置年份
        cal.set(Calendar.YEAR, year);
        // 设置月份
        cal.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        // 设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }

    public static int getMonth(Date date){
		DateTime dateTime = new DateTime(date);
		return dateTime.getMonthOfYear();
	}

	public static int getYear(Date date){
		DateTime dateTime = new DateTime(date);
		return dateTime.getYear();
	}

	public static Integer timeBetween(String prevTime , String nowTime , TimeUnit timeUnit) throws Exception {
		DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
		if(prevTime.contains(".")){
			prevTime = prevTime.substring(0 , prevTime.lastIndexOf("."));
		}

		if(nowTime.contains(".")){
			nowTime = nowTime.substring(0 , nowTime.lastIndexOf("."));
		}
		DateTime prevDateTime = dateTimeFormat.parseDateTime(prevTime);
		DateTime nowDateTime = dateTimeFormat.parseDateTime(nowTime);
		if(timeUnit.equals(TimeUnit.DAYS)){
			return Days.daysBetween(prevDateTime , nowDateTime).getDays();
		}else if(timeUnit.equals(TimeUnit.HOURS)){
			return Hours.hoursBetween(prevDateTime , nowDateTime).getHours();
		}else if(timeUnit.equals(TimeUnit.MINUTES)){
			return Minutes.minutesBetween(prevDateTime , nowDateTime).getMinutes();
		}else if(timeUnit.equals(TimeUnit.SECONDS)){
			return Seconds.secondsBetween(prevDateTime , nowDateTime).getSeconds();
		}else {
			throw new Exception("timeBetween Exec Error | TimeUnit Can Not Match | TimeUnit = " + timeUnit);
		}
	}

	public static Integer timeBetween(Long prevTime , Long nowTime , TimeUnit timeUnit) throws Exception {
		DateTime prevDateTime = new DateTime(prevTime);
		DateTime nowDateTime = new DateTime(nowTime);
		if(timeUnit.equals(TimeUnit.DAYS)){
			return Days.daysBetween(prevDateTime , nowDateTime).getDays();
		}else if(timeUnit.equals(TimeUnit.HOURS)){
			return Hours.hoursBetween(prevDateTime , nowDateTime).getHours();
		}else if(timeUnit.equals(TimeUnit.MINUTES)){
			return Minutes.minutesBetween(prevDateTime , nowDateTime).getMinutes();
		}else if(timeUnit.equals(TimeUnit.SECONDS)){
			return Seconds.secondsBetween(prevDateTime , nowDateTime).getSeconds();
		}else {
			throw new Exception("timeBetween Exec Error | TimeUnit Can Not Match | TimeUnit = " + timeUnit);
		}
	}

	public static void main(String[] args) throws ParseException {

		String lastWeek = getLastWeek(3);
		System.out.println(lastWeek);
//		System.out.println(getYear(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2020-12-11 00:00:00")));
	}

    /*
	 * 其他常用
	 * 
	 * 获取年月日点分秒
		DateTime dateTime = new DateTime();
		int year = dateTime.getYear();
		int month = dateTime.getMonthOfYear();
		int day = dateTime.getDayOfMonth();
		int week = dateTime.getDayOfWeek();
		int hour = dateTime.getHourOfDay();
		int min = dateTime.getMinuteOfHour();
		int sec = dateTime.getSecondOfMinute();
		int msec = dateTime.getMillisOfSecond();
	 * 
	 * 日期前后推算
		DateTime dateTime = new DateTime();
		DateTime yesterday = dateTime.minusDays(1);
		DateTime tomorrow = dateTime.plusDays(1);
		DateTime before1month = dateTime.minusMonths(1);
		DateTime after3month = dateTime.plusMonths(3);
		DateTime before2year = dateTime.minusYears(2);
		DateTime after5year = dateTime.plusYears(5);
	 * 
	 * 特殊日期
		// 上个月最后一天
		dateTime.minusMonths(1).dayOfMonth().withMaximumValue().toString("yyyy-MM-dd");
		// 下个月第一天
		dateTime.plusMonths(1).dayOfMonth().withMinimumValue().toString("yyyy-MM-dd");
	 * 
	 */

}
